package com.phonemap;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;

import com.google.appengine.api.datastore.Blob;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.phonemap.common.Util;
import com.phonemap.models.Photo;

@SuppressWarnings("serial")
public class PhotoServlet extends BaseServlet {
	private static final Logger logger = Logger.getLogger(PhotoServlet.class
			.getCanonicalName());

	/**
	 * Get the requested photo entities in JSON format
	 */
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		super.doGet(req, resp);
		String action = req.getParameter("action");
		if ("display".equals(action)) {
			long id = Long.parseLong(req.getParameter("id").replace("_", "")); // WTF?
			String userId = req.getParameter("userId");
			showRecord(id, userId, req, resp);
			return;
		}
		logger.log(Level.INFO, "Obtaining Photo listing");
		String searchFor = req.getParameter("q");
		PrintWriter out = resp.getWriter();
		Iterable<Entity> entities = null;
		if (searchFor == null || searchFor.equals("")) {
			entities = Photo.getAllPhotos();
			out.println(Util.writeJSON(entities));
		} else {
			entities = Photo.getPhoto(searchFor);
			out.println(Util.writeJSON(entities));
		}
		return;
	}

	/**
	 * Insert the new photo
	 */
	protected void doPut(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// logger.log(Level.INFO, "Creating Photo");
		// String userId = req.getParameter("user");
		// String title = req.getParameter("title");
		// String caption = req.getParameter("caption");
		// String contentType = req.getParameter("contentType");
		// req.getp
		// InputStream is = req.getInputStream();
		// ByteArrayOutputStream os = new ByteArrayOutputStream();
		// Streams.copy(is, os, true);
		//
		// byte[] photoData = os.toByteArray();
		//
		// Photo.createOrUpdatePhoto(userId, title, caption, contentType,
		// photoData, null);
		ServletFileUpload upload = new ServletFileUpload();
		String userId = null, title = null, caption = null, contentType = null;
		byte[] photoData = null;
		try {

			FileItemIterator it = upload.getItemIterator(req);

			while (it.hasNext()) {
				FileItemStream item = it.next();
				String fieldName = item.getFieldName();
				InputStream fieldValue = item.openStream();

				if ("user".equals(fieldName)) {
					userId = Streams.asString(fieldValue);
					continue;
				}

				if ("title".equals(fieldName)) {
					title = Streams.asString(fieldValue);
					continue;
				}

				if ("caption".equals(fieldName)) {
					caption = Streams.asString(fieldValue);
					continue;
				}

				if ("file".equals(fieldName)) {
					contentType = item.getContentType();
					ByteArrayOutputStream out = new ByteArrayOutputStream();
					Streams.copy(fieldValue, out, true);
					photoData = out.toByteArray();
					continue;
				}
			}

			Photo.createOrUpdatePhoto(userId, title, caption, contentType,
					photoData, null);
		} catch (FileUploadException e) {
			throw new ServletException(e);
		}
	}

	/**
	 * Delete the photo
	 */
	protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		logger.log(Level.INFO, "Deleting order from the listing");
		String photoId = req.getParameter("id");
		String phone = req.getParameter("parentid");

		Key parentKey = KeyFactory.createKey("User", phone);
		Key key = KeyFactory.createKey(parentKey, "Photo",
				Integer.parseInt(photoId));
		Util.deleteEntity(key);
	}

	/**
	 * Redirect the call to doDelete or doPut method
	 */
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		ServletFileUpload upload = new ServletFileUpload();
		String action = "";
		try {
			action = req.getParameter("action");
			if (action == null) {
				// form data
				String userId = null, title = null, caption = null, contentType = null;
				byte[] photoData = null;
				FileItemIterator it = upload.getItemIterator(req);

				while (it.hasNext()) {
					FileItemStream item = it.next();
					String fieldName = item.getFieldName();
					InputStream fieldValue = item.openStream();

					if ("action".equals(fieldName)) {
						action = Streams.asString(fieldValue);
						continue;
					}

					if ("user".equals(fieldName)) {
						userId = Streams.asString(fieldValue);
						continue;
					}

					if ("title".equals(fieldName)) {
						title = Streams.asString(fieldValue);
						continue;
					}

					if ("caption".equals(fieldName)) {
						caption = Streams.asString(fieldValue);
						continue;
					}

					if ("file".equals(fieldName)) {
						contentType = item.getContentType();
						ByteArrayOutputStream out = new ByteArrayOutputStream();
						Streams.copy(fieldValue, out, true);
						photoData = out.toByteArray();
						continue;
					}
				}

				if (action.equalsIgnoreCase("put")) {
					Photo.createOrUpdatePhoto(userId, title, caption,
							contentType, photoData, null);
					return;
				}
			}

			if (action.equalsIgnoreCase("delete")) {
				doDelete(req, resp);
				return;
			} else if (action.equalsIgnoreCase("put")) {
				doPut(req, resp);
				return;
			}
		} catch (FileUploadException e) {
			throw new ServletException(e);
		}

	}

	protected void showRecord(long id, String userId, HttpServletRequest req,
			HttpServletResponse resp) throws ServletException, IOException {
		
		Entity photo = Photo.findPhotoById(id, userId);
		if (photo != null) {
			Map<String, Object> properties = photo.getProperties();
			for (String key : properties.keySet()) {
				if (key.equals("contentType")) {
					resp.setContentType(properties.get(key).toString());
				} else if (key.equals("photoData")) {
					Blob blob = (Blob)properties.get(key);  
					resp.getOutputStream().write(
							blob.getBytes());
				}

			}
		}
		
		resp.flushBuffer();
	}
}
